<template>
  <div>
    <div id="simulation" style="margin: 0 auto; max-width: 600px;"></div>

    <div>
      <span>进度</span>
      <Progress :percent="25" style="margin-bottom: 11px;" />
      <Button type="success" @click="handleStart">开始</Button>
      <Button type="warning" @click="handlePause">暂停</Button>
      <Button type="error" @click="handleStop">结束</Button>
      <Button type="info" @click="handleGoBack">返回</Button>
      <Button type="success" @click="handleSave">保存</Button>

    </div>
  </div>
</template>

<script>
  import G2 from '@antv/g2';
  var Canvas2Image = function () {

    // check if support sth.
    var $support = function () {
      var canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d');

      return {
        canvas: !!ctx,
        imageData: !!ctx.getImageData,
        dataURL: !!canvas.toDataURL,
        btoa: !!window.btoa
      };
    }();

    var downloadMime = 'image/octet-stream';

    function scaleCanvas (canvas, width, height) {
      var w = canvas.width,
        h = canvas.height;
      if (width == undefined) {
        width = w;
      }
      if (height == undefined) {
        height = h;
      }

      var retCanvas = document.createElement('canvas');
      var retCtx = retCanvas.getContext('2d');
      retCanvas.width = width;
      retCanvas.height = height;
      retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
      return retCanvas;
    }

    function getDataURL (canvas, type, width, height) {
      canvas = scaleCanvas(canvas, width, height);
      return canvas.toDataURL(type);
    }

    function saveFile (strData) {
      document.location.href = strData;
    }

    function genImage(strData) {
      var img = document.createElement('img');
      img.src = strData;
      return img;
    }
    function fixType (type) {
      type = type.toLowerCase().replace(/jpg/i, 'jpeg');
      var r = type.match(/png|jpeg|bmp|gif/)[0];
      return 'image/' + r;
    }
    function encodeData (data) {
      if (!window.btoa) { throw 'btoa undefined' }
      var str = '';
      if (typeof data == 'string') {
        str = data;
      } else {
        for (var i = 0; i < data.length; i ++) {
          str += String.fromCharCode(data[i]);
        }
      }

      return btoa(str);
    }
    function getImageData (canvas) {
      var w = canvas.width,
        h = canvas.height;
      return canvas.getContext('2d').getImageData(0, 0, w, h);
    }
    function makeURI (strData, type) {
      return 'data:' + type + ';base64,' + strData;
    }


    /**
     * create bitmap image
     * 按照规则生成图片响应头和响应体
     */
    var genBitmapImage = function (oData) {

      //
      // BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
      // BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
      //

      var biWidth  = oData.width;
      var biHeight    = oData.height;
      var biSizeImage = biWidth * biHeight * 3;
      var bfSize  = biSizeImage + 54; // total header size = 54 bytes

      //
      //  typedef struct tagBITMAPFILEHEADER {
      //      WORD bfType;
      //      DWORD bfSize;
      //      WORD bfReserved1;
      //      WORD bfReserved2;
      //      DWORD bfOffBits;
      //  } BITMAPFILEHEADER;
      //
      var BITMAPFILEHEADER = [
        // WORD bfType -- The file type signature; must be "BM"
        0x42, 0x4D,
        // DWORD bfSize -- The size, in bytes, of the bitmap file
        bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
        // WORD bfReserved1 -- Reserved; must be zero
        0, 0,
        // WORD bfReserved2 -- Reserved; must be zero
        0, 0,
        // DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
        54, 0, 0, 0
      ];

      //
      //  typedef struct tagBITMAPINFOHEADER {
      //      DWORD biSize;
      //      LONG  biWidth;
      //      LONG  biHeight;
      //      WORD  biPlanes;
      //      WORD  biBitCount;
      //      DWORD biCompression;
      //      DWORD biSizeImage;
      //      LONG  biXPelsPerMeter;
      //      LONG  biYPelsPerMeter;
      //      DWORD biClrUsed;
      //      DWORD biClrImportant;
      //  } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
      //
      var BITMAPINFOHEADER = [
        // DWORD biSize -- The number of bytes required by the structure
        40, 0, 0, 0,
        // LONG biWidth -- The width of the bitmap, in pixels
        biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
        // LONG biHeight -- The height of the bitmap, in pixels
        biHeight & 0xff, biHeight >> 8  & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
        // WORD biPlanes -- The number of planes for the target device. This value must be set to 1
        1, 0,
        // WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
        // has a maximum of 2^24 colors (16777216, Truecolor)
        24, 0,
        // DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
        0, 0, 0, 0,
        // DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
        biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
        // LONG biXPelsPerMeter, unused
        0,0,0,0,
        // LONG biYPelsPerMeter, unused
        0,0,0,0,
        // DWORD biClrUsed, the number of color indexes of palette, unused
        0,0,0,0,
        // DWORD biClrImportant, unused
        0,0,0,0
      ];

      var iPadding = (4 - ((biWidth * 3) % 4)) % 4;

      var aImgData = oData.data;

      var strPixelData = '';
      var biWidth4 = biWidth<<2;
      var y = biHeight;
      var fromCharCode = String.fromCharCode;

      do {
        var iOffsetY = biWidth4*(y-1);
        var strPixelRow = '';
        for (var x = 0; x < biWidth; x++) {
          var iOffsetX = x<<2;
          strPixelRow += fromCharCode(aImgData[iOffsetY+iOffsetX+2]) +
            fromCharCode(aImgData[iOffsetY+iOffsetX+1]) +
            fromCharCode(aImgData[iOffsetY+iOffsetX]);
        }

        for (var c = 0; c < iPadding; c++) {
          strPixelRow += String.fromCharCode(0);
        }

        strPixelData += strPixelRow;
      } while (--y);

      var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);

      return strEncoded;
    };

    /**
     * saveAsImage
     * @param canvasElement
     * @param {String} image type
     * @param {Number} [optional] png width
     * @param {Number} [optional] png height
     */
    var saveAsImage = function (canvas, width, height, type) {
      if ($support.canvas && $support.dataURL) {
        if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
        if (type == undefined) { type = 'png'; }
        type = fixType(type);
        if (/bmp/.test(type)) {
          var data = getImageData(scaleCanvas(canvas, width, height));
          var strData = genBitmapImage(data);
          saveFile(makeURI(strData, downloadMime));
        } else {
          var strData = getDataURL(canvas, type, width, height);
          saveFile(strData.replace(type, downloadMime));
        }
      }
    };

    var convertToImage = function (canvas, width, height, type) {
      if ($support.canvas && $support.dataURL) {
        if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
        if (type == undefined) { type = 'png'; }
        type = fixType(type);

        if (/bmp/.test(type)) {
          var data = getImageData(scaleCanvas(canvas, width, height));
          var strData = genBitmapImage(data);
          return genImage(makeURI(strData, 'image/bmp'));
        } else {
          var strData = getDataURL(canvas, type, width, height);
          return genImage(strData);
        }
      }
    };



    return {
      saveAsImage: saveAsImage,
      saveAsPNG: function (canvas, width, height) {
        return saveAsImage(canvas, width, height, 'png');
      },
      saveAsJPEG: function (canvas, width, height) {
        return saveAsImage(canvas, width, height, 'jpeg');
      },
      saveAsGIF: function (canvas, width, height) {
        return saveAsImage(canvas, width, height, 'gif');
      },
      saveAsBMP: function (canvas, width, height) {
        return saveAsImage(canvas, width, height, 'bmp');
      },

      convertToImage: convertToImage,
      convertToPNG: function (canvas, width, height) {
        return convertToImage(canvas, width, height, 'png');
      },
      convertToJPEG: function (canvas, width, height) {
        return convertToImage(canvas, width, height, 'jpeg');
      },
      convertToGIF: function (canvas, width, height) {
        return convertToImage(canvas, width, height, 'gif');
      },
      convertToBMP: function (canvas, width, height) {
        return convertToImage(canvas, width, height, 'bmp');
      }
    };

  }();


  var chart
  export default {
    name: 'simulate',
    data() {
      return {
        timer: 0,
        testData: []
      }
    },
    methods: {
      handleGoBack() {
        this.$emit('back')
      },
      handlePause() {
        clearInterval(this.timer)
      },
      handleStop() {
        clearInterval(this.timer)

      },
      handleSave() {
        let canvas = document.querySelector('#simulation canvas')
        Canvas2Image.saveAsPNG(canvas, 1000, 800)
      },
      handleStart() {
        var that = this
        this.timer = setInterval(() => {
          var now = new Date();
          var time = now.getTime();
          var value1 = ~~30 + Math.random() * 50;
          var direction = Math.random() > 0.5 ? 1 : -1;
          var value2 = value1 + Math.random() * 20 * direction;
          if (that.testData.length >= 200) {
            that.testData.shift();
            that.testData.shift();
          }
          that.testData.push({
            time: time,
            value: value2,
            type: 'yesterday'
          });
          that.testData.push({
            time: time,
            value: value1,
            type: 'today'
          });

          if (that.testData.length > 20) {
            that.testData.shift();
            that.testData.shift();
          }
          chart.changeData(that.testData);
        }, 1000);
      }
    },
    mounted() {
      var that = this
      var data = [];
      chart = new G2.Chart({
        container: 'simulation',
        // forceFit: true,
        height: 400,
        width: 500,
        padding: [10, 100, 50, 50]
      });
      chart.source(that.testData, {
        time: {
          alias: '时间',
          type: 'time',
          mask: 'MM:ss',
          nice: false
        },
        value: {
          alias: '占用率',
          min: 0,
          max: 120
        },
        type: {
          type: 'cat'
        }
      });
      chart.axis('predict', false);
      chart.legend({
        attachLast: true
      });
      chart.legend('predict', false);
      chart.line().position('time*value').shape('smooth').color('type', ['#cccccc', '#2593fc']).size(2).animate({
        update: {
          duration: 0
        }
      });
      chart.guide().line({
        top: true,
        start: ['min', 60],
        end: ['max', 60],

        lineStyle: {
          stroke: '#F5222D',
          lineWidth: 2
        },
        text: {
          content: '预警线',
          position: 'start',
          offsetX: 20,
          offsetY: -5,
          style: {
            fontSize: 14,
            fill: '#F5222D',
            opacity: 0.5
          }
        }
      });
      chart.guide().regionFilter({
        top: true,
        start: ['min', 60],
        end: ['max', 100],
        color: '#F5222D',
        apply: ['line']
      });
      chart.guide().dataMarker({
        top: true,
        content: '当前最大峰值',
        position: function position() {
          var obj = findMax();
          if (obj) {
            return [obj.time, obj.value];
          }
          return [0, 0];
        },

        style: {
          text: {
            fontSize: 13
          },
          point: {
            stroke: '#606060'
          }
        },
        lineLength: 50
      });
      chart.render();


      function findMax() {
        var maxValue = 0;
        var maxObj = null;
        for (var i = 0; i < that.testData.length; i++) {
          var d = that.testData[i];
          if (d.value > maxValue /* && d.type === 'today'*/ ) {
            maxValue = d.value;
            maxObj = d;
          }
        }
        return maxObj;
      }
    }
  }
</script>

<style scoped>

</style>
